package test;

import com.zzh.fullscreen.AirPlane;
import com.zzh.fullscreen.Bullet;
import com.zzh.fullscreen.Flyer;
import com.zzh.fullscreen.Player;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
import java.util.Timer;
import java.util.*;

/**
 *
 */
public class Draw extends JPanel implements Runnable {
    private static final long serialVersionUID = 100L;

    public final static int START = 0;
    public static final int RUNNING = 1;
    public static final int PAUSE = 2;
    public static final int NEXT_MISSION = 3;
    public static final int GAME_FINSH = 4;
    public static final int GAME_OVER = 5;

    static BufferedImage[] back_img = null;
    static BufferedImage start_bg_img = null;
    static BufferedImage startbut_img = null;
    static BufferedImage logo = null;
    static BufferedImage continue_img = null;
    static int startImgX = 170;
    static int startImgY = 560;
    public static int screenWidth;
    public static int screenHeight;

    private int hy1 = 0;
    private int hy2 = 0;

    int mission;
    Timer timer;
    public int state = -1;

    Player player;
    List<Flash> flashs;
    LinkedList<FlashBoom> flashBooms;
    int opponentAirPlaneNum = 0;
    int maxOpponentAirPlaneNum = 50;
    /**
     * 当前场景敌人列表
     */
    LinkedList<AirPlane> opponentAirPlanes;
    Timer timeTask;
    Random rand;
    FlashBoom flashBoom;
    long start = 0;
    long end = 0;
    int fps = 0, currentFPS = 0;

    /** 静态代码块，给静态资源图片初始化 **/
    static {
        back_img = new BufferedImage[4];
        try {
            for (int i = 0; i < back_img.length; i++) {
                back_img[i] = ImageIO.read(Draw.class.getClassLoader()
                        .getResourceAsStream(
                                "img/img_bg_level_" + (i + 1) + ".jpg"));
            }

            screenWidth = back_img[0].getWidth();
            screenHeight = back_img[0].getHeight();

            start_bg_img = ImageIO.read(Draw.class.getClassLoader()
                    .getResourceAsStream(
                            "img/img_bg_logo.jpg"));
            startbut_img = ImageIO.read(Draw.class.getClassLoader()
                    .getResourceAsStream(
                            "img/startbut.png"));
            logo = ImageIO.read(Draw.class.getClassLoader()
                    .getResourceAsStream(
                            "img/logo.png"));

            continue_img = ImageIO.read(Draw.class.getClassLoader()
                    .getResourceAsStream(
                            "img/continue.png"));
        } catch (IOException e) {
            System.out.println("载入背景资源异常！");
            e.printStackTrace();
        }
    }

    public Draw(String missionStr) {
        //if (missionStr.equals("第一关")) {
        //    this.mission = 0;
        //} else if (missionStr.equals("第二关")) {
        //    this.mission = 1;
        //} else if (missionStr.equals("第三关")) {
        //    this.mission = 2;
        //} else {
        //    this.mission = 3;
        //}
        this.mission = 0;

        player = new Player(180, 600);

        opponentAirPlanes = new LinkedList<AirPlane>();
        flashs = Collections.synchronizedList(new LinkedList<Flash>());
        flashBooms = new LinkedList<FlashBoom>();

//		enableEvents(AWTEvent.KEY_EVENT_MASK);
        rand = new Random(System.currentTimeMillis());
        timeTask = new Timer();

        this.addKeyListener(player);
        this.addMouseMotionListener(player);
        this.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (state == START) {
                    if (e.getX() > startImgX && e.getX() < startImgX + startbut_img.getWidth() &&
                            e.getY() > startImgY && e.getY() < startImgY + startbut_img.getHeight()) {
                        state = RUNNING;
                        System.out.println("RUNNING");
                    }
                    //回到开始界面
                } else if (state == GAME_OVER || state == GAME_FINSH) {
                    opponentAirPlanes.clear();
                    flashBooms.clear();
                    AirPlane.getBulletList().clear();
                    player.getBulletList().clear();
                    opponentAirPlaneNum = 0;
                    state = START;
                } else if (state == NEXT_MISSION) {
                    if (mission < 3) {
                        mission++;
                    }
                    state = RUNNING;
                }
            }
        });
        state = START;
        //state = GAME_OVER;
        //state = NEXT_MISSION;
        //state = PAUSE;

        setFocusable(true);
        //定时随机产生敌机
        autoGenerateOpponentPlan();

        timer = new Timer(); //
        timer.schedule(new TimerTask() {
            @Override

            public void run() {
                if (state >= -1) {
                    Draw.this.repaint();
                }
            }

        }, 0, 10);
    }

    /**
     * 显示开始界面
     **/
    private void paintStart(Graphics g) {
        g.drawImage(start_bg_img, 0, 0, this);
        g.drawImage(logo, 60, 100, logo.getWidth() * 2 / 3, logo.getHeight() * 2 / 3, this);
        g.drawImage(startbut_img, startImgX, startImgY, this);
    }

    /**
     * 定时随机产生敌机
     */
    public void autoGenerateOpponentPlan() {
        start = System.currentTimeMillis();
        timeTask.schedule(new TimerTask() {
            @Override
            public void run() {
                if (state == RUNNING) {
                    if (opponentAirPlaneNum++ < maxOpponentAirPlaneNum) {
                        AirPlane e = new AirPlane(rand.nextInt(screenWidth
                                - AirPlane.img[0].getWidth() / 2), -AirPlane.img[0]
                                .getHeight(), 1);
                        opponentAirPlanes.add(e);
                    }
                }
            }
        }, 1000, 1000);
    }

    public void runningPaint(Graphics g) {
        paintBackground(g);

        paintAirPlane(g);

        player.paint(g);

        paintAllBullet(g);

        paintFlash(g);

        paintFlashBoom(g);
    }

    public void step() {
        for (int i = 0; i < opponentAirPlanes.size(); i++) {
            AirPlane a = opponentAirPlanes.get(i);
            if (a.getY() > this.screenHeight) {
                opponentAirPlanes.remove(a);
            }
        }
        if (opponentAirPlaneNum >= maxOpponentAirPlaneNum && opponentAirPlanes.isEmpty()) {
            if (mission >= 3) {
                state = GAME_FINSH;
            } else {
                opponentAirPlaneNum = 0;
                maxOpponentAirPlaneNum += 50;
                state = NEXT_MISSION;
            }
        }

        player.step();

        stepAllBullet();
    }

    /**
     * 重写paint方法
     */
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        if (state == START) {
            paintStart(g);
        } else if (state == PAUSE) {
            runningPaint(g);
            drawGamePause(g);
        } else if (state == RUNNING) {
            runningPaint(g);
            step();
        } else if (state == NEXT_MISSION) {
            drawNextMission(g);
        } else if (state == GAME_FINSH) {
            drawGameFinsh(g);
        } else if (state == GAME_OVER) {
            runningPaint(g);
            drawGameOver(g);
        }
        paintFPS(g);
    }

    public void drawNextMission(Graphics g) {
        g.drawImage(start_bg_img, 0, 0, this);
        Font f = new Font(null, Font.BOLD, 32);
        //g.setColor(Color.ORANGE);
        g.setFont(f);
        g.setColor(new Color(250, 110, 110));
        g.drawString("你已完成当前关卡，点击继续。", 20, Draw.screenHeight / 2 - 60);
    }

    public void drawGameFinsh(Graphics g) {
        g.drawImage(start_bg_img, 0, 0, this);
        Font f = new Font(null, Font.BOLD, 32);
        //g.setColor(Color.ORANGE);
        g.setFont(f);
        g.setColor(new Color(250, 110, 110));
        g.drawString("你已完成所有关卡", 110, Draw.screenHeight / 2 - 60);
    }

    public void drawGamePause(Graphics g) {
        g.drawImage(start_bg_img, 0, 0, this);
        g.drawImage(continue_img, 120, 500, this);
        Font f = new Font(null, Font.BOLD, 32);
        //g.setColor(Color.ORANGE);
        g.setFont(f);
        g.setColor(new Color(50, 110, 50));
        g.drawString("游戏暂停", 180, Draw.screenHeight / 2 - 160);
    }

    public void drawGameOver(Graphics g) {
        g.drawImage(start_bg_img, 0, 0, this);
        Font f = new Font(null, Font.BOLD, 32);
        //g.setColor(Color.ORANGE);
        g.setFont(f);
        g.setColor(new Color(100, 110, 110));
        g.drawString("游戏结束,当前分数" + player.getScore(), 120, Draw.screenHeight / 2 - 60);
    }

    public void run() {
        while (true) {
            this.repaint();
            try {
                Thread.sleep(20);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /*** 显示FPS **/
    public void paintFPS(Graphics g) {
        fps++;
        end = System.currentTimeMillis();
        if (end - start >= 1000) {
            currentFPS = fps;
            this.fps = 0;
            start = System.currentTimeMillis();
        }

        Font f = new Font(null, Font.BOLD, 24);
        g.setFont(f);
        g.setColor(new Color(250, 250, 180));
        g.drawString("FPS:" + currentFPS, 8, 20);
        //g.setColor(new Color(250, 250, 180));
        g.drawString("LIFE:" + player.getLife(), 8, 42);
        g.drawString("SCORE:" + player.getScore(), 8, 64);
    }

    /**
     * 显示敌机
     **/
    public void paintAirPlane(Graphics g) {
        for (int i = 0; i < opponentAirPlanes.size(); i++) {
            AirPlane a = opponentAirPlanes.get(i);
            a.step();
            a.paint(g);
            //敌机跟玩家碰撞
            if (a.intersectTo(player)) {
                flashBoom = new FlashBoom(a.getX() + a.getWidth() / 2, a.getY());
                flashBooms.add(flashBoom);

                opponentAirPlanes.remove(a);
                player.dowFireType();

                if (player.getLife() < 0) {
                    state = GAME_OVER;
                }
            }
        }
    }

    /******** 子弹逻辑 ********/
    public void stepAllBullet() {
        player.autoShoot();
        /******** 敌机子弹碰撞 ********/
        List<Bullet> bulletList = null;
        bulletList = AirPlane.getBulletList();
        for (int i = 0; i < bulletList.size(); i++) {
            Bullet b = bulletList.get(i);
            b.updataXY();
            if (b.intersectTo(player)) {
                flashBoom = new FlashBoom(b.getX() + b.getWidth() / 2,
                        b.getY());
                System.out.println("new flashBoom");
                flashBooms.add(flashBoom);
                bulletList.remove(b);
                player.dowFireType();
                if (player.getLife() < 0) {
                    state = GAME_OVER;
                }
            } else if (b.outOfbounds()) {
                bulletList.remove(b);
            }
        }

        /*** 玩家子弹碰撞 **/
        bulletList = player.getBulletList();
        for (int i = 0; i < bulletList.size(); i++) {
            Bullet b = bulletList.get(i);
            b.updataXY();
            for (int j = 0; j < opponentAirPlanes.size(); j++) {
                AirPlane a = opponentAirPlanes.get(j);
                if (b.intersectTo(a)) {
                    flashBoom = new FlashBoom(b.getX() + b.getWidth() / 2,
                            b.getY() + b.getHeight() / 2);
                    //g.drawLine(b.getX() + b.getWidth() / 2, 0, b.getY() + b.getHeight() / 2, 700);
                    System.out.println("new flash");
                    flashBooms.add(flashBoom);
                    opponentAirPlanes.remove(a);
                    bulletList.remove(b);
                    player.setScoer(a.getScore());
                    switch (a.getType()) {
                        case 2:
                            player.upFireType();
                            break;
                        case 3:
                            player.addLife();
                            break;
                    }
                    break;
                } else if (b.outOfbounds()) {
                    bulletList.remove(b);
                }
            }
        }

    }

    /******** 子弹逻辑 ********/
    public void paintAllBullet(Graphics g) {
        List<Bullet> bulletList = null;
        bulletList = AirPlane.getBulletList();
        for (int i = 0; i < bulletList.size(); i++) {
            Bullet b = bulletList.get(i);
            b.paint(g, Flyer.DOWN);
        }
        /*** 玩家子弹碰撞 **/
        bulletList = player.getBulletList();
        for (int i = 0; i < bulletList.size(); i++) {
            Bullet b = bulletList.get(i);
            b.updataXY();
            b.paint(g, Flyer.UP);
        }
    }

    /**
     * 显示爆炸动画
     **/
    public void paintFlash(Graphics g) {
        for (Flash f : flashs) {
            if (f.fps != 0) {
                f.paint(g);
            }
        }
        /** 移除爆炸动画 **/
        for (int i = 0; i < flashs.size(); i++) {
            Flash f = flashs.get(i);
            if (f.fps == 0) {
                flashs.remove(f);
            }
        }
    }

    /**
     * 显示爆炸动画
     **/
    public void paintFlashBoom(Graphics g) {
        for (FlashBoom f : flashBooms) {
            if (f.fps != 0) {
                f.paint(g);
            }
        }
        /** 移除爆炸动画 **/
        for (int i = 0; i < flashBooms.size(); i++) {
            FlashBoom f = flashBooms.get(i);
            if (f.fps == 0) {
                flashBooms.remove(f);
            }
        }
    }

    /**
     * 显示背景
     **/
    private void paintBackground(Graphics g) {
        if (hy1 >= 0)
            hy1 = -screenHeight;
        if (hy1 <= 0 && hy2 >= -screenHeight)
            g.drawImage(back_img[mission], 0, hy1 += 1, this);
        hy2 = hy1 + screenHeight;
        if (hy2 >= 0 && hy2 <= screenHeight)
            g.drawImage(back_img[mission], 0, hy2, this);
    }
}
